Project 5: Vehicle Detection

1 Import all needed libraries

In [58]:
# Import libraries
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import glob
import time
import math
import cv2
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.utils import shuffle
from sklearn.svm import LinearSVC
from scipy.ndimage.measurements import label
from skimage.feature import hog
%matplotlib inline

2 Load car and non-car images sets

In [15]:
# loading raw car images
car_extracted = glob.glob('vehicles/KITTI_extracted/*.png')
car_right = glob.glob('vehicles/GTI_Right/image*.png')
car_middle_close = glob.glob('vehicles/GTI_MiddleClose/image*.png')
car_far = glob.glob('vehicles/GTI_Far/image*.png')
car_left = glob.glob('vehicles/GTI_Left/image*.png')
# loading raw non car images
non_car_gti = glob.glob('non-vehicles/GTI/image*.png')
non_car_extras = glob.glob('non-vehicles/Extras/extra*.png')

# combile all car sets together
cars = car_far + car_left + car_right + car_middle_close + car_extracted
# combile all non car sets together
non_cars = non_car_gti + non_car_extras

# shuffling the car raw images
shuffle(cars)
# shuffling the raw non car images
shuffle(non_cars)
Out[15]:
['non-vehicles/Extras/extra5688.png',
 'non-vehicles/Extras/extra4603.png',
 'non-vehicles/Extras/extra1820.png',
 'non-vehicles/GTI/image2161.png',
 'non-vehicles/Extras/extra2024.png',
 'non-vehicles/Extras/extra2568.png',
 'non-vehicles/GTI/image581.png',
 'non-vehicles/GTI/image1671.png',
 'non-vehicles/GTI/image2011.png',
 'non-vehicles/Extras/extra3528.png',
 'non-vehicles/GTI/image1348.png',
 'non-vehicles/Extras/extra5365.png',
 'non-vehicles/Extras/extra1527.png',
 'non-vehicles/GTI/image2088.png',
 'non-vehicles/Extras/extra152.png',
 'non-vehicles/Extras/extra1718.png',
 'non-vehicles/GTI/image762.png',
 'non-vehicles/Extras/extra3305.png',
 'non-vehicles/Extras/extra1872.png',
 'non-vehicles/Extras/extra2569.png',
 'non-vehicles/Extras/extra1796.png',
 'non-vehicles/GTI/image822.png',
 'non-vehicles/Extras/extra1258.png',
 'non-vehicles/Extras/extra4641.png',
 'non-vehicles/GTI/image679.png',
 'non-vehicles/Extras/extra810.png',
 'non-vehicles/Extras/extra5380.png',
 'non-vehicles/Extras/extra5198.png',
 'non-vehicles/Extras/extra406.png',
 'non-vehicles/GTI/image1593.png',
 'non-vehicles/Extras/extra98.png',
 'non-vehicles/GTI/image1327.png',
 'non-vehicles/Extras/extra493.png',
 'non-vehicles/Extras/extra327.png',
 'non-vehicles/GTI/image1924.png',
 'non-vehicles/GTI/image202.png',
 'non-vehicles/GTI/image3597.png',
 'non-vehicles/GTI/image3208.png',
 'non-vehicles/Extras/extra1996.png',
 'non-vehicles/GTI/image737.png',
 'non-vehicles/Extras/extra4858.png',
 'non-vehicles/Extras/extra1969.png',
 'non-vehicles/GTI/image302.png',
 'non-vehicles/Extras/extra5389.png',
 'non-vehicles/GTI/image2139.png',
 'non-vehicles/Extras/extra4151.png',
 'non-vehicles/Extras/extra4996.png',
 'non-vehicles/GTI/image1946.png',
 'non-vehicles/GTI/image3079.png',
 'non-vehicles/Extras/extra3364.png',
 'non-vehicles/GTI/image3567.png',
 'non-vehicles/Extras/extra4619.png',
 'non-vehicles/Extras/extra2898.png',
 'non-vehicles/GTI/image3164.png',
 'non-vehicles/GTI/image36.png',
 'non-vehicles/GTI/image2695.png',
 'non-vehicles/Extras/extra3146.png',
 'non-vehicles/Extras/extra4624.png',
 'non-vehicles/GTI/image846.png',
 'non-vehicles/Extras/extra2468.png',
 'non-vehicles/Extras/extra631.png',
 'non-vehicles/GTI/image2788.png',
 'non-vehicles/Extras/extra4102.png',
 'non-vehicles/GTI/image195.png',
 'non-vehicles/Extras/extra173.png',
 'non-vehicles/Extras/extra5455.png',
 'non-vehicles/GTI/image1156.png',
 'non-vehicles/Extras/extra4481.png',
 'non-vehicles/Extras/extra3978.png',
 'non-vehicles/Extras/extra3941.png',
 'non-vehicles/GTI/image3681.png',
 'non-vehicles/Extras/extra2446.png',
 'non-vehicles/Extras/extra1208.png',
 'non-vehicles/GTI/image136.png',
 'non-vehicles/Extras/extra5496.png',
 'non-vehicles/GTI/image1015.png',
 'non-vehicles/Extras/extra2962.png',
 'non-vehicles/GTI/image2896.png',
 'non-vehicles/Extras/extra2136.png',
 'non-vehicles/Extras/extra1744.png',
 'non-vehicles/Extras/extra957.png',
 'non-vehicles/GTI/image1864.png',
 'non-vehicles/Extras/extra4786.png',
 'non-vehicles/Extras/extra671.png',
 'non-vehicles/Extras/extra5762.png',
 'non-vehicles/Extras/extra4993.png',
 'non-vehicles/Extras/extra3596.png',
 'non-vehicles/GTI/image1165.png',
 'non-vehicles/Extras/extra4954.png',
 'non-vehicles/GTI/image1100.png',
 'non-vehicles/GTI/image413.png',
 'non-vehicles/Extras/extra3380.png',
 'non-vehicles/Extras/extra1610.png',
 'non-vehicles/Extras/extra3031.png',
 'non-vehicles/GTI/image532.png',
 'non-vehicles/Extras/extra5566.png',
 'non-vehicles/Extras/extra3915.png',
 'non-vehicles/Extras/extra5409.png',
 'non-vehicles/GTI/image2098.png',
 'non-vehicles/GTI/image1817.png',
 'non-vehicles/Extras/extra394.png',
 'non-vehicles/Extras/extra337.png',
 'non-vehicles/GTI/image3804.png',
 'non-vehicles/GTI/image3897.png',
 'non-vehicles/Extras/extra3529.png',
 'non-vehicles/Extras/extra1265.png',
 'non-vehicles/Extras/extra2833.png',
 'non-vehicles/Extras/extra1627.png',
 'non-vehicles/Extras/extra5216.png',
 'non-vehicles/GTI/image34.png',
 'non-vehicles/GTI/image2843.png',
 'non-vehicles/GTI/image1727.png',
 'non-vehicles/Extras/extra654.png',
 'non-vehicles/Extras/extra659.png',
 'non-vehicles/Extras/extra3337.png',
 'non-vehicles/GTI/image1419.png',
 'non-vehicles/GTI/image2448.png',
 'non-vehicles/Extras/extra2985.png',
 'non-vehicles/GTI/image2809.png',
 'non-vehicles/Extras/extra1349.png',
 'non-vehicles/Extras/extra769.png',
 'non-vehicles/Extras/extra4133.png',
 'non-vehicles/GTI/image1123.png',
 'non-vehicles/Extras/extra4868.png',
 'non-vehicles/Extras/extra230.png',
 'non-vehicles/GTI/image2569.png',
 'non-vehicles/GTI/image421.png',
 'non-vehicles/GTI/image2459.png',
 'non-vehicles/GTI/image2363.png',
 'non-vehicles/Extras/extra627.png',
 'non-vehicles/Extras/extra3539.png',
 'non-vehicles/Extras/extra372.png',
 'non-vehicles/GTI/image3546.png',
 'non-vehicles/Extras/extra2513.png',
 'non-vehicles/Extras/extra5423.png',
 'non-vehicles/Extras/extra2828.png',
 'non-vehicles/Extras/extra8.png',
 'non-vehicles/GTI/image2693.png',
 'non-vehicles/GTI/image178.png',
 'non-vehicles/Extras/extra5652.png',
 'non-vehicles/Extras/extra3922.png',
 'non-vehicles/Extras/extra1089.png',
 'non-vehicles/Extras/extra4331.png',
 'non-vehicles/Extras/extra2551.png',
 'non-vehicles/Extras/extra3921.png',
 'non-vehicles/GTI/image2204.png',
 'non-vehicles/GTI/image3582.png',
 'non-vehicles/GTI/image402.png',
 'non-vehicles/Extras/extra2932.png',
 'non-vehicles/Extras/extra5707.png',
 'non-vehicles/Extras/extra2792.png',
 'non-vehicles/Extras/extra2057.png',
 'non-vehicles/Extras/extra3568.png',
 'non-vehicles/Extras/extra3514.png',
 'non-vehicles/Extras/extra4093.png',
 'non-vehicles/Extras/extra2283.png',
 'non-vehicles/GTI/image1031.png',
 'non-vehicles/Extras/extra4161.png',
 'non-vehicles/GTI/image286.png',
 'non-vehicles/Extras/extra1717.png',
 'non-vehicles/Extras/extra1118.png',
 'non-vehicles/Extras/extra5415.png',
 'non-vehicles/Extras/extra5132.png',
 'non-vehicles/GTI/image563.png',
 'non-vehicles/Extras/extra5505.png',
 'non-vehicles/Extras/extra3114.png',
 'non-vehicles/GTI/image2771.png',
 'non-vehicles/Extras/extra5180.png',
 'non-vehicles/Extras/extra2431.png',
 'non-vehicles/Extras/extra3787.png',
 'non-vehicles/Extras/extra2363.png',
 'non-vehicles/Extras/extra2704.png',
 'non-vehicles/Extras/extra4605.png',
 'non-vehicles/Extras/extra356.png',
 'non-vehicles/GTI/image2034.png',
 'non-vehicles/GTI/image2052.png',
 'non-vehicles/Extras/extra2286.png',
 'non-vehicles/GTI/image3123.png',
 'non-vehicles/GTI/image1767.png',
 'non-vehicles/Extras/extra2046.png',
 'non-vehicles/Extras/extra2475.png',
 'non-vehicles/Extras/extra4604.png',
 'non-vehicles/GTI/image2864.png',
 'non-vehicles/Extras/extra4185.png',
 'non-vehicles/Extras/extra4052.png',
 'non-vehicles/Extras/extra5641.png',
 'non-vehicles/GTI/image2727.png',
 'non-vehicles/Extras/extra4449.png',
 'non-vehicles/Extras/extra74.png',
 'non-vehicles/Extras/extra5125.png',
 'non-vehicles/Extras/extra1973.png',
 'non-vehicles/Extras/extra3206.png',
 'non-vehicles/GTI/image3251.png',
 'non-vehicles/Extras/extra3427.png',
 'non-vehicles/Extras/extra4530.png',
 'non-vehicles/Extras/extra583.png',
 'non-vehicles/GTI/image3574.png',
 'non-vehicles/GTI/image3304.png',
 'non-vehicles/Extras/extra4419.png',
 'non-vehicles/GTI/image3398.png',
 'non-vehicles/GTI/image141.png',
 'non-vehicles/GTI/image729.png',
 'non-vehicles/Extras/extra4771.png',
 'non-vehicles/Extras/extra5741.png',
 'non-vehicles/Extras/extra2935.png',
 'non-vehicles/GTI/image64.png',
 'non-vehicles/Extras/extra586.png',
 'non-vehicles/GTI/image2848.png',
 'non-vehicles/Extras/extra5261.png',
 'non-vehicles/GTI/image3168.png',
 'non-vehicles/Extras/extra712.png',
 'non-vehicles/Extras/extra729.png',
 'non-vehicles/GTI/image2.png',
 'non-vehicles/Extras/extra2808.png',
 'non-vehicles/Extras/extra3156.png',
 'non-vehicles/GTI/image2012.png',
 'non-vehicles/Extras/extra5551.png',
 'non-vehicles/Extras/extra1526.png',
 'non-vehicles/Extras/extra3324.png',
 'non-vehicles/GTI/image3738.png',
 'non-vehicles/GTI/image627.png',
 'non-vehicles/GTI/image3441.png',
 'non-vehicles/Extras/extra1912.png',
 'non-vehicles/Extras/extra2284.png',
 'non-vehicles/GTI/image2302.png',
 'non-vehicles/GTI/image3824.png',
 'non-vehicles/GTI/image3348.png',
 'non-vehicles/Extras/extra2730.png',
 'non-vehicles/Extras/extra1406.png',
 'non-vehicles/GTI/image2593.png',
 'non-vehicles/Extras/extra1790.png',
 'non-vehicles/GTI/image3127.png',
 'non-vehicles/GTI/image836.png',
 'non-vehicles/Extras/extra2686.png',
 'non-vehicles/GTI/image92.png',
 'non-vehicles/GTI/image3326.png',
 'non-vehicles/GTI/image166.png',
 'non-vehicles/Extras/extra1292.png',
 'non-vehicles/Extras/extra3569.png',
 'non-vehicles/GTI/image2692.png',
 'non-vehicles/Extras/extra3242.png',
 'non-vehicles/GTI/image2362.png',
 'non-vehicles/Extras/extra2224.png',
 'non-vehicles/GTI/image2704.png',
 'non-vehicles/GTI/image251.png',
 'non-vehicles/Extras/extra634.png',
 'non-vehicles/GTI/image589.png',
 'non-vehicles/GTI/image78.png',
 'non-vehicles/Extras/extra1472.png',
 'non-vehicles/GTI/image3516.png',
 'non-vehicles/Extras/extra3263.png',
 'non-vehicles/GTI/image819.png',
 'non-vehicles/GTI/image681.png',
 'non-vehicles/GTI/image3802.png',
 'non-vehicles/Extras/extra2419.png',
 'non-vehicles/Extras/extra5618.png',
 'non-vehicles/Extras/extra45.png',
 'non-vehicles/Extras/extra4532.png',
 'non-vehicles/GTI/image1278.png',
 'non-vehicles/Extras/extra1213.png',
 'non-vehicles/Extras/extra1334.png',
 'non-vehicles/Extras/extra816.png',
 'non-vehicles/GTI/image2010.png',
 'non-vehicles/Extras/extra235.png',
 'non-vehicles/GTI/image818.png',
 'non-vehicles/GTI/image2031.png',
 'non-vehicles/GTI/image2119.png',
 'non-vehicles/Extras/extra402.png',
 'non-vehicles/Extras/extra202.png',
 'non-vehicles/GTI/image614.png',
 'non-vehicles/GTI/image153.png',
 'non-vehicles/GTI/image2364.png',
 'non-vehicles/Extras/extra4807.png',
 'non-vehicles/GTI/image533.png',
 'non-vehicles/GTI/image3258.png',
 'non-vehicles/Extras/extra2642.png',
 'non-vehicles/Extras/extra5431.png',
 'non-vehicles/Extras/extra3951.png',
 'non-vehicles/Extras/extra1507.png',
 'non-vehicles/GTI/image1577.png',
 'non-vehicles/GTI/image1063.png',
 'non-vehicles/Extras/extra3160.png',
 'non-vehicles/Extras/extra3825.png',
 'non-vehicles/Extras/extra5279.png',
 'non-vehicles/Extras/extra1977.png',
 'non-vehicles/GTI/image993.png',
 'non-vehicles/GTI/image852.png',
 'non-vehicles/GTI/image1693.png',
 'non-vehicles/Extras/extra3856.png',
 'non-vehicles/GTI/image2023.png',
 'non-vehicles/GTI/image759.png',
 'non-vehicles/GTI/image2495.png',
 'non-vehicles/GTI/image2292.png',
 'non-vehicles/Extras/extra3254.png',
 'non-vehicles/GTI/image2918.png',
 'non-vehicles/Extras/extra5683.png',
 'non-vehicles/GTI/image3618.png',
 'non-vehicles/Extras/extra5616.png',
 'non-vehicles/Extras/extra2478.png',
 'non-vehicles/Extras/extra3498.png',
 'non-vehicles/Extras/extra3232.png',
 'non-vehicles/Extras/extra672.png',
 'non-vehicles/GTI/image1299.png',
 'non-vehicles/Extras/extra2360.png',
 'non-vehicles/GTI/image267.png',
 'non-vehicles/GTI/image3322.png',
 'non-vehicles/Extras/extra4960.png',
 'non-vehicles/Extras/extra2770.png',
 'non-vehicles/Extras/extra2412.png',
 'non-vehicles/GTI/image1538.png',
 'non-vehicles/Extras/extra4037.png',
 'non-vehicles/Extras/extra818.png',
 'non-vehicles/Extras/extra5592.png',
 'non-vehicles/GTI/image546.png',
 'non-vehicles/GTI/image658.png',
 'non-vehicles/GTI/image3629.png',
 'non-vehicles/GTI/image2989.png',
 'non-vehicles/Extras/extra1209.png',
 'non-vehicles/GTI/image75.png',
 'non-vehicles/Extras/extra4872.png',
 'non-vehicles/Extras/extra5034.png',
 'non-vehicles/Extras/extra3659.png',
 'non-vehicles/GTI/image2895.png',
 'non-vehicles/Extras/extra391.png',
 'non-vehicles/Extras/extra2784.png',
 'non-vehicles/Extras/extra3235.png',
 'non-vehicles/Extras/extra3841.png',
 'non-vehicles/Extras/extra5396.png',
 'non-vehicles/GTI/image859.png',
 'non-vehicles/Extras/extra3304.png',
 'non-vehicles/GTI/image3112.png',
 'non-vehicles/GTI/image2113.png',
 'non-vehicles/Extras/extra5123.png',
 'non-vehicles/Extras/extra4830.png',
 'non-vehicles/Extras/extra1531.png',
 'non-vehicles/GTI/image2377.png',
 'non-vehicles/GTI/image10.png',
 'non-vehicles/GTI/image2222.png',
 'non-vehicles/Extras/extra2225.png',
 'non-vehicles/Extras/extra466.png',
 'non-vehicles/Extras/extra3544.png',
 'non-vehicles/GTI/image2901.png',
 'non-vehicles/GTI/image1637.png',
 'non-vehicles/Extras/extra1957.png',
 'non-vehicles/Extras/extra469.png',
 'non-vehicles/Extras/extra1806.png',
 'non-vehicles/Extras/extra5519.png',
 'non-vehicles/GTI/image90.png',
 'non-vehicles/GTI/image1412.png',
 'non-vehicles/Extras/extra361.png',
 'non-vehicles/Extras/extra2544.png',
 'non-vehicles/GTI/image2207.png',
 'non-vehicles/GTI/image1440.png',
 'non-vehicles/GTI/image1317.png',
 'non-vehicles/Extras/extra4201.png',
 'non-vehicles/GTI/image675.png',
 'non-vehicles/Extras/extra15.png',
 'non-vehicles/GTI/image2260.png',
 'non-vehicles/Extras/extra2715.png',
 'non-vehicles/Extras/extra41.png',
 'non-vehicles/GTI/image805.png',
 'non-vehicles/GTI/image3591.png',
 'non-vehicles/Extras/extra809.png',
 'non-vehicles/GTI/image2880.png',
 'non-vehicles/Extras/extra3331.png',
 'non-vehicles/Extras/extra1152.png',
 'non-vehicles/GTI/image1110.png',
 'non-vehicles/Extras/extra2971.png',
 'non-vehicles/Extras/extra1109.png',
 'non-vehicles/Extras/extra3310.png',
 'non-vehicles/GTI/image1736.png',
 'non-vehicles/GTI/image525.png',
 'non-vehicles/GTI/image3091.png',
 'non-vehicles/Extras/extra4402.png',
 'non-vehicles/Extras/extra673.png',
 'non-vehicles/GTI/image3176.png',
 'non-vehicles/Extras/extra154.png',
 'non-vehicles/Extras/extra3224.png',
 'non-vehicles/GTI/image2605.png',
 'non-vehicles/GTI/image2232.png',
 'non-vehicles/GTI/image3195.png',
 'non-vehicles/Extras/extra29.png',
 'non-vehicles/GTI/image3646.png',
 'non-vehicles/Extras/extra2425.png',
 'non-vehicles/GTI/image1880.png',
 'non-vehicles/Extras/extra2179.png',
 'non-vehicles/Extras/extra657.png',
 'non-vehicles/Extras/extra5565.png',
 'non-vehicles/GTI/image2543.png',
 'non-vehicles/GTI/image1080.png',
 'non-vehicles/GTI/image1492.png',
 'non-vehicles/GTI/image1684.png',
 'non-vehicles/GTI/image1032.png',
 'non-vehicles/Extras/extra4810.png',
 'non-vehicles/Extras/extra2146.png',
 'non-vehicles/GTI/image1000.png',
 'non-vehicles/Extras/extra25.png',
 'non-vehicles/GTI/image690.png',
 'non-vehicles/GTI/image2950.png',
 'non-vehicles/Extras/extra1033.png',
 'non-vehicles/GTI/image3460.png',
 'non-vehicles/Extras/extra4550.png',
 'non-vehicles/Extras/extra1561.png',
 'non-vehicles/Extras/extra4036.png',
 'non-vehicles/GTI/image1328.png',
 'non-vehicles/Extras/extra3554.png',
 'non-vehicles/GTI/image714.png',
 'non-vehicles/Extras/extra72.png',
 'non-vehicles/Extras/extra1695.png',
 'non-vehicles/Extras/extra3461.png',
 'non-vehicles/Extras/extra4150.png',
 'non-vehicles/GTI/image2995.png',
 'non-vehicles/GTI/image557.png',
 'non-vehicles/GTI/image2030.png',
 'non-vehicles/Extras/extra560.png',
 'non-vehicles/Extras/extra2717.png',
 'non-vehicles/Extras/extra3754.png',
 'non-vehicles/Extras/extra4869.png',
 'non-vehicles/GTI/image23.png',
 'non-vehicles/Extras/extra1336.png',
 'non-vehicles/Extras/extra272.png',
 'non-vehicles/Extras/extra64.png',
 'non-vehicles/Extras/extra1637.png',
 'non-vehicles/GTI/image2421.png',
 'non-vehicles/Extras/extra5323.png',
 'non-vehicles/Extras/extra5293.png',
 'non-vehicles/GTI/image1448.png',
 'non-vehicles/Extras/extra2242.png',
 'non-vehicles/GTI/image72.png',
 'non-vehicles/Extras/extra4403.png',
 'non-vehicles/Extras/extra2875.png',
 'non-vehicles/Extras/extra5375.png',
 'non-vehicles/GTI/image1653.png',
 'non-vehicles/Extras/extra446.png',
 'non-vehicles/Extras/extra437.png',
 'non-vehicles/Extras/extra160.png',
 'non-vehicles/Extras/extra5447.png',
 'non-vehicles/Extras/extra3064.png',
 'non-vehicles/GTI/image3202.png',
 'non-vehicles/GTI/image757.png',
 'non-vehicles/Extras/extra3580.png',
 'non-vehicles/Extras/extra1460.png',
 'non-vehicles/Extras/extra878.png',
 'non-vehicles/Extras/extra2076.png',
 'non-vehicles/GTI/image3443.png',
 'non-vehicles/GTI/image1358.png',
 'non-vehicles/Extras/extra1625.png',
 'non-vehicles/GTI/image542.png',
 'non-vehicles/Extras/extra2699.png',
 'non-vehicles/Extras/extra2131.png',
 'non-vehicles/GTI/image1938.png',
 'non-vehicles/GTI/image2391.png',
 'non-vehicles/GTI/image1800.png',
 'non-vehicles/Extras/extra4704.png',
 'non-vehicles/Extras/extra2683.png',
 'non-vehicles/GTI/image810.png',
 'non-vehicles/Extras/extra3108.png',
 'non-vehicles/Extras/extra870.png',
 'non-vehicles/Extras/extra775.png',
 'non-vehicles/Extras/extra4010.png',
 'non-vehicles/GTI/image696.png',
 'non-vehicles/GTI/image135.png',
 'non-vehicles/Extras/extra763.png',
 'non-vehicles/GTI/image3189.png',
 'non-vehicles/GTI/image798.png',
 'non-vehicles/GTI/image15.png',
 'non-vehicles/Extras/extra4360.png',
 'non-vehicles/Extras/extra1797.png',
 'non-vehicles/Extras/extra5359.png',
 'non-vehicles/Extras/extra5764.png',
 'non-vehicles/Extras/extra746.png',
 'non-vehicles/GTI/image620.png',
 'non-vehicles/Extras/extra5562.png',
 'non-vehicles/GTI/image2770.png',
 'non-vehicles/GTI/image2087.png',
 'non-vehicles/GTI/image246.png',
 'non-vehicles/Extras/extra3670.png',
 'non-vehicles/Extras/extra2823.png',
 'non-vehicles/Extras/extra4391.png',
 'non-vehicles/GTI/image2584.png',
 'non-vehicles/GTI/image3700.png',
 'non-vehicles/Extras/extra2927.png',
 'non-vehicles/Extras/extra2221.png',
 'non-vehicles/Extras/extra4369.png',
 'non-vehicles/Extras/extra1379.png',
 'non-vehicles/Extras/extra2552.png',
 'non-vehicles/GTI/image2018.png',
 'non-vehicles/GTI/image962.png',
 'non-vehicles/GTI/image742.png',
 'non-vehicles/Extras/extra409.png',
 'non-vehicles/GTI/image26.png',
 'non-vehicles/Extras/extra342.png',
 'non-vehicles/Extras/extra2584.png',
 'non-vehicles/Extras/extra5679.png',
 'non-vehicles/GTI/image3634.png',
 'non-vehicles/Extras/extra580.png',
 'non-vehicles/Extras/extra2655.png',
 'non-vehicles/Extras/extra3268.png',
 'non-vehicles/Extras/extra1960.png',
 'non-vehicles/GTI/image1371.png',
 'non-vehicles/Extras/extra4372.png',
 'non-vehicles/Extras/extra1979.png',
 'non-vehicles/Extras/extra3197.png',
 'non-vehicles/GTI/image3805.png',
 'non-vehicles/GTI/image878.png',
 'non-vehicles/Extras/extra5202.png',
 'non-vehicles/GTI/image1799.png',
 'non-vehicles/Extras/extra3489.png',
 'non-vehicles/GTI/image2590.png',
 'non-vehicles/Extras/extra5710.png',
 'non-vehicles/Extras/extra5628.png',
 'non-vehicles/Extras/extra4344.png',
 'non-vehicles/GTI/image1916.png',
 'non-vehicles/GTI/image3507.png',
 'non-vehicles/Extras/extra1564.png',
 'non-vehicles/Extras/extra2886.png',
 'non-vehicles/Extras/extra848.png',
 'non-vehicles/GTI/image1140.png',
 'non-vehicles/Extras/extra791.png',
 'non-vehicles/Extras/extra1658.png',
 'non-vehicles/Extras/extra822.png',
 'non-vehicles/GTI/image3362.png',
 'non-vehicles/Extras/extra4404.png',
 'non-vehicles/Extras/extra4706.png',
 'non-vehicles/Extras/extra4486.png',
 'non-vehicles/Extras/extra3275.png',
 'non-vehicles/Extras/extra1794.png',
 'non-vehicles/GTI/image3111.png',
 'non-vehicles/GTI/image127.png',
 'non-vehicles/Extras/extra682.png',
 'non-vehicles/Extras/extra3458.png',
 'non-vehicles/Extras/extra3392.png',
 'non-vehicles/GTI/image3454.png',
 'non-vehicles/GTI/image3509.png',
 'non-vehicles/GTI/image1979.png',
 'non-vehicles/Extras/extra727.png',
 'non-vehicles/GTI/image3242.png',
 'non-vehicles/GTI/image236.png',
 'non-vehicles/GTI/image1214.png',
 'non-vehicles/GTI/image3569.png',
 'non-vehicles/Extras/extra4218.png',
 'non-vehicles/Extras/extra2210.png',
 'non-vehicles/GTI/image1447.png',
 'non-vehicles/GTI/image2679.png',
 'non-vehicles/Extras/extra5061.png',
 'non-vehicles/GTI/image2765.png',
 'non-vehicles/Extras/extra5008.png',
 'non-vehicles/GTI/image2717.png',
 'non-vehicles/Extras/extra110.png',
 'non-vehicles/Extras/extra4547.png',
 'non-vehicles/Extras/extra629.png',
 'non-vehicles/GTI/image31.png',
 'non-vehicles/Extras/extra919.png',
 'non-vehicles/Extras/extra2548.png',
 'non-vehicles/GTI/image2354.png',
 'non-vehicles/Extras/extra2356.png',
 'non-vehicles/GTI/image672.png',
 'non-vehicles/Extras/extra2967.png',
 'non-vehicles/GTI/image3223.png',
 'non-vehicles/Extras/extra4155.png',
 'non-vehicles/GTI/image3043.png',
 'non-vehicles/GTI/image3764.png',
 'non-vehicles/Extras/extra5129.png',
 'non-vehicles/Extras/extra5567.png',
 'non-vehicles/GTI/image700.png',
 'non-vehicles/GTI/image88.png',
 'non-vehicles/Extras/extra250.png',
 'non-vehicles/Extras/extra5155.png',
 'non-vehicles/Extras/extra2877.png',
 'non-vehicles/Extras/extra2496.png',
 'non-vehicles/Extras/extra1649.png',
 'non-vehicles/Extras/extra4682.png',
 'non-vehicles/GTI/image3674.png',
 'non-vehicles/Extras/extra688.png',
 'non-vehicles/GTI/image2649.png',
 'non-vehicles/GTI/image2230.png',
 'non-vehicles/Extras/extra3748.png',
 'non-vehicles/Extras/extra3521.png',
 'non-vehicles/GTI/image1504.png',
 'non-vehicles/Extras/extra4030.png',
 'non-vehicles/GTI/image1223.png',
 'non-vehicles/GTI/image1773.png',
 'non-vehicles/GTI/image2243.png',
 'non-vehicles/Extras/extra2703.png',
 'non-vehicles/Extras/extra3606.png',
 'non-vehicles/GTI/image1840.png',
 'non-vehicles/Extras/extra5047.png',
 'non-vehicles/GTI/image253.png',
 'non-vehicles/Extras/extra4125.png',
 'non-vehicles/Extras/extra5306.png',
 'non-vehicles/Extras/extra3454.png',
 'non-vehicles/Extras/extra1863.png',
 'non-vehicles/GTI/image1246.png',
 'non-vehicles/Extras/extra5247.png',
 'non-vehicles/GTI/image535.png',
 'non-vehicles/GTI/image484.png',
 'non-vehicles/GTI/image2517.png',
 'non-vehicles/Extras/extra1494.png',
 'non-vehicles/Extras/extra5021.png',
 'non-vehicles/Extras/extra2486.png',
 'non-vehicles/Extras/extra3581.png',
 'non-vehicles/Extras/extra1567.png',
 'non-vehicles/GTI/image156.png',
 'non-vehicles/Extras/extra4501.png',
 'non-vehicles/Extras/extra1408.png',
 'non-vehicles/Extras/extra5624.png',
 'non-vehicles/Extras/extra2471.png',
 'non-vehicles/GTI/image2499.png',
 'non-vehicles/GTI/image3060.png',
 'non-vehicles/Extras/extra2540.png',
 'non-vehicles/GTI/image3282.png',
 'non-vehicles/Extras/extra2827.png',
 'non-vehicles/Extras/extra1155.png',
 'non-vehicles/Extras/extra3935.png',
 'non-vehicles/Extras/extra2036.png',
 'non-vehicles/Extras/extra2849.png',
 'non-vehicles/Extras/extra2543.png',
 'non-vehicles/GTI/image481.png',
 'non-vehicles/Extras/extra3281.png',
 'non-vehicles/GTI/image1043.png',
 'non-vehicles/Extras/extra5366.png',
 'non-vehicles/Extras/extra3527.png',
 'non-vehicles/GTI/image1295.png',
 'non-vehicles/Extras/extra5493.png',
 'non-vehicles/Extras/extra4001.png',
 'non-vehicles/Extras/extra5165.png',
 'non-vehicles/GTI/image1320.png',
 'non-vehicles/Extras/extra894.png',
 'non-vehicles/GTI/image2146.png',
 'non-vehicles/GTI/image3670.png',
 'non-vehicles/Extras/extra1234.png',
 'non-vehicles/GTI/image1213.png',
 'non-vehicles/GTI/image3615.png',
 'non-vehicles/Extras/extra3595.png',
 'non-vehicles/GTI/image965.png',
 'non-vehicles/GTI/image2574.png',
 'non-vehicles/GTI/image655.png',
 'non-vehicles/GTI/image999.png',
 'non-vehicles/Extras/extra197.png',
 'non-vehicles/Extras/extra2731.png',
 'non-vehicles/GTI/image573.png',
 'non-vehicles/GTI/image1047.png',
 'non-vehicles/GTI/image2426.png',
 'non-vehicles/GTI/image2317.png',
 'non-vehicles/GTI/image1685.png',
 'non-vehicles/GTI/image1712.png',
 'non-vehicles/GTI/image754.png',
 'non-vehicles/GTI/image1534.png',
 'non-vehicles/Extras/extra722.png',
 'non-vehicles/Extras/extra1512.png',
 'non-vehicles/Extras/extra4031.png',
 'non-vehicles/Extras/extra639.png',
 'non-vehicles/GTI/image3235.png',
 'non-vehicles/GTI/image2701.png',
 'non-vehicles/Extras/extra4464.png',
 'non-vehicles/Extras/extra4591.png',
 'non-vehicles/Extras/extra5507.png',
 'non-vehicles/Extras/extra5609.png',
 'non-vehicles/GTI/image666.png',
 'non-vehicles/GTI/image3447.png',
 'non-vehicles/Extras/extra996.png',
 'non-vehicles/Extras/extra306.png',
 'non-vehicles/GTI/image2345.png',
 'non-vehicles/GTI/image2162.png',
 'non-vehicles/Extras/extra4454.png',
 'non-vehicles/GTI/image3439.png',
 'non-vehicles/Extras/extra3175.png',
 'non-vehicles/Extras/extra5751.png',
 'non-vehicles/Extras/extra5178.png',
 'non-vehicles/GTI/image808.png',
 'non-vehicles/GTI/image1948.png',
 'non-vehicles/Extras/extra5258.png',
 'non-vehicles/Extras/extra370.png',
 'non-vehicles/Extras/extra4736.png',
 'non-vehicles/Extras/extra563.png',
 'non-vehicles/Extras/extra5289.png',
 'non-vehicles/Extras/extra1287.png',
 'non-vehicles/GTI/image3482.png',
 'non-vehicles/Extras/extra2483.png',
 'non-vehicles/Extras/extra237.png',
 'non-vehicles/Extras/extra4015.png',
 'non-vehicles/GTI/image14.png',
 'non-vehicles/GTI/image467.png',
 'non-vehicles/Extras/extra5700.png',
 'non-vehicles/GTI/image1444.png',
 'non-vehicles/Extras/extra363.png',
 'non-vehicles/GTI/image269.png',
 'non-vehicles/Extras/extra2661.png',
 'non-vehicles/Extras/extra1225.png',
 'non-vehicles/GTI/image1198.png',
 'non-vehicles/Extras/extra5119.png',
 'non-vehicles/GTI/image576.png',
 'non-vehicles/GTI/image3172.png',
 'non-vehicles/GTI/image568.png',
 'non-vehicles/Extras/extra5649.png',
 'non-vehicles/Extras/extra2203.png',
 'non-vehicles/Extras/extra2129.png',
 'non-vehicles/Extras/extra1849.png',
 'non-vehicles/Extras/extra2860.png',
 'non-vehicles/Extras/extra4174.png',
 'non-vehicles/GTI/image2202.png',
 'non-vehicles/GTI/image717.png',
 'non-vehicles/GTI/image2352.png',
 'non-vehicles/GTI/image1717.png',
 'non-vehicles/Extras/extra4764.png',
 'non-vehicles/GTI/image2084.png',
 'non-vehicles/Extras/extra2322.png',
 'non-vehicles/GTI/image1202.png',
 'non-vehicles/GTI/image327.png',
 'non-vehicles/Extras/extra2115.png',
 'non-vehicles/Extras/extra3832.png',
 'non-vehicles/GTI/image2763.png',
 'non-vehicles/Extras/extra221.png',
 'non-vehicles/GTI/image2658.png',
 'non-vehicles/GTI/image3345.png',
 'non-vehicles/Extras/extra378.png',
 'non-vehicles/GTI/image490.png',
 'non-vehicles/Extras/extra3369.png',
 'non-vehicles/GTI/image1871.png',
 'non-vehicles/Extras/extra1684.png',
 'non-vehicles/GTI/image2356.png',
 'non-vehicles/Extras/extra4184.png',
 'non-vehicles/Extras/extra3622.png',
 'non-vehicles/Extras/extra1773.png',
 'non-vehicles/GTI/image1897.png',
 'non-vehicles/GTI/image3578.png',
 'non-vehicles/GTI/image1827.png',
 'non-vehicles/Extras/extra4129.png',
 'non-vehicles/Extras/extra998.png',
 'non-vehicles/Extras/extra522.png',
 'non-vehicles/Extras/extra2561.png',
 'non-vehicles/GTI/image13.png',
 'non-vehicles/GTI/image1161.png',
 'non-vehicles/Extras/extra1904.png',
 'non-vehicles/GTI/image3341.png',
 'non-vehicles/GTI/image2135.png',
 'non-vehicles/Extras/extra5388.png',
 'non-vehicles/GTI/image489.png',
 'non-vehicles/GTI/image339.png',
 'non-vehicles/GTI/image2892.png',
 'non-vehicles/GTI/image3472.png',
 'non-vehicles/GTI/image2506.png',
 'non-vehicles/GTI/image220.png',
 'non-vehicles/Extras/extra1967.png',
 'non-vehicles/GTI/image3793.png',
 'non-vehicles/Extras/extra984.png',
 'non-vehicles/Extras/extra5328.png',
 'non-vehicles/GTI/image123.png',
 'non-vehicles/Extras/extra3276.png',
 'non-vehicles/GTI/image1119.png',
 'non-vehicles/Extras/extra3161.png',
 'non-vehicles/Extras/extra5196.png',
 'non-vehicles/Extras/extra3478.png',
 'non-vehicles/Extras/extra2734.png',
 'non-vehicles/GTI/image2582.png',
 'non-vehicles/Extras/extra3934.png',
 'non-vehicles/GTI/image2190.png',
 'non-vehicles/Extras/extra495.png',
 'non-vehicles/GTI/image3158.png',
 'non-vehicles/GTI/image3693.png',
 'non-vehicles/GTI/image512.png',
 'non-vehicles/GTI/image1939.png',
 'non-vehicles/Extras/extra1382.png',
 'non-vehicles/Extras/extra3117.png',
 'non-vehicles/Extras/extra1568.png',
 'non-vehicles/GTI/image1659.png',
 'non-vehicles/GTI/image3870.png',
 'non-vehicles/GTI/image1641.png',
 'non-vehicles/GTI/image258.png',
 'non-vehicles/Extras/extra3453.png',
 'non-vehicles/GTI/image2623.png',
 'non-vehicles/GTI/image3665.png',
 'non-vehicles/Extras/extra5498.png',
 'non-vehicles/Extras/extra253.png',
 'non-vehicles/Extras/extra4458.png',
 'non-vehicles/Extras/extra3228.png',
 'non-vehicles/Extras/extra5441.png',
 'non-vehicles/GTI/image3165.png',
 'non-vehicles/GTI/image3368.png',
 'non-vehicles/Extras/extra5164.png',
 'non-vehicles/Extras/extra4743.png',
 'non-vehicles/Extras/extra5449.png',
 'non-vehicles/GTI/image2219.png',
 'non-vehicles/GTI/image1010.png',
 'non-vehicles/GTI/image3266.png',
 'non-vehicles/Extras/extra3882.png',
 'non-vehicles/Extras/extra1452.png',
 'non-vehicles/GTI/image491.png',
 'non-vehicles/Extras/extra2025.png',
 'non-vehicles/Extras/extra4798.png',
 'non-vehicles/GTI/image594.png',
 'non-vehicles/Extras/extra3647.png',
 'non-vehicles/Extras/extra2781.png',
 'non-vehicles/GTI/image206.png',
 'non-vehicles/GTI/image1967.png',
 'non-vehicles/Extras/extra5721.png',
 'non-vehicles/GTI/image214.png',
 'non-vehicles/Extras/extra1174.png',
 'non-vehicles/Extras/extra702.png',
 'non-vehicles/Extras/extra1450.png',
 'non-vehicles/Extras/extra3709.png',
 'non-vehicles/GTI/image3128.png',
 'non-vehicles/Extras/extra3695.png',
 'non-vehicles/GTI/image2729.png',
 'non-vehicles/Extras/extra314.png',
 'non-vehicles/Extras/extra1097.png',
 'non-vehicles/Extras/extra126.png',
 'non-vehicles/Extras/extra5620.png',
 'non-vehicles/Extras/extra892.png',
 'non-vehicles/GTI/image2067.png',
 'non-vehicles/GTI/image530.png',
 'non-vehicles/Extras/extra5305.png',
 'non-vehicles/GTI/image3643.png',
 'non-vehicles/Extras/extra5726.png',
 'non-vehicles/GTI/image1005.png',
 'non-vehicles/GTI/image3259.png',
 'non-vehicles/Extras/extra4765.png',
 'non-vehicles/Extras/extra955.png',
 'non-vehicles/GTI/image985.png',
 'non-vehicles/GTI/image1147.png',
 'non-vehicles/Extras/extra2635.png',
 'non-vehicles/Extras/extra2961.png',
 'non-vehicles/Extras/extra2094.png',
 'non-vehicles/Extras/extra1756.png',
 'non-vehicles/Extras/extra5346.png',
 'non-vehicles/GTI/image3551.png',
 'non-vehicles/Extras/extra2965.png',
 'non-vehicles/Extras/extra2135.png',
 'non-vehicles/Extras/extra2816.png',
 'non-vehicles/GTI/image2861.png',
 'non-vehicles/Extras/extra5759.png',
 'non-vehicles/Extras/extra5149.png',
 'non-vehicles/GTI/image2054.png',
 'non-vehicles/Extras/extra3381.png',
 'non-vehicles/Extras/extra4219.png',
 'non-vehicles/Extras/extra979.png',
 'non-vehicles/GTI/image2481.png',
 'non-vehicles/GTI/image1393.png',
 'non-vehicles/Extras/extra3804.png',
 'non-vehicles/Extras/extra5635.png',
 'non-vehicles/GTI/image1089.png',
 'non-vehicles/GTI/image2341.png',
 'non-vehicles/GTI/image1775.png',
 'non-vehicles/GTI/image2828.png',
 'non-vehicles/Extras/extra2501.png',
 'non-vehicles/GTI/image3102.png',
 'non-vehicles/Extras/extra3726.png',
 'non-vehicles/GTI/image3796.png',
 'non-vehicles/Extras/extra68.png',
 'non-vehicles/Extras/extra1661.png',
 'non-vehicles/GTI/image1835.png',
 'non-vehicles/Extras/extra935.png',
 'non-vehicles/GTI/image2210.png',
 'non-vehicles/Extras/extra87.png',
 'non-vehicles/Extras/extra4803.png',
 'non-vehicles/Extras/extra1008.png',
 'non-vehicles/Extras/extra3601.png',
 'non-vehicles/GTI/image3579.png',
 'non-vehicles/Extras/extra4895.png',
 'non-vehicles/Extras/extra4482.png',
 'non-vehicles/GTI/image3616.png',
 'non-vehicles/GTI/image3692.png',
 'non-vehicles/Extras/extra5245.png',
 'non-vehicles/Extras/extra4186.png',
 'non-vehicles/GTI/image1520.png',
 'non-vehicles/Extras/extra2571.png',
 'non-vehicles/GTI/image1053.png',
 'non-vehicles/GTI/image1499.png',
 'non-vehicles/GTI/image2664.png',
 'non-vehicles/Extras/extra4935.png',
 'non-vehicles/Extras/extra3626.png',
 'non-vehicles/Extras/extra1572.png',
 'non-vehicles/GTI/image2220.png',
 'non-vehicles/Extras/extra3597.png',
 'non-vehicles/Extras/extra2542.png',
 'non-vehicles/Extras/extra3492.png',
 'non-vehicles/GTI/image3584.png',
 'non-vehicles/GTI/image3213.png',
 'non-vehicles/Extras/extra2711.png',
 'non-vehicles/Extras/extra4477.png',
 'non-vehicles/Extras/extra3728.png',
 'non-vehicles/GTI/image554.png',
 'non-vehicles/GTI/image1277.png',
 'non-vehicles/Extras/extra1873.png',
 'non-vehicles/Extras/extra4726.png',
 'non-vehicles/Extras/extra5744.png',
 'non-vehicles/GTI/image3053.png',
 'non-vehicles/Extras/extra2996.png',
 'non-vehicles/Extras/extra3823.png',
 'non-vehicles/GTI/image3557.png',
 'non-vehicles/Extras/extra542.png',
 'non-vehicles/Extras/extra2323.png',
 'non-vehicles/GTI/image1392.png',
 'non-vehicles/Extras/extra5760.png',
 'non-vehicles/Extras/extra70.png',
 'non-vehicles/GTI/image2521.png',
 'non-vehicles/GTI/image2237.png',
 'non-vehicles/Extras/extra2248.png',
 'non-vehicles/Extras/extra3589.png',
 'non-vehicles/GTI/image3307.png',
 'non-vehicles/GTI/image3351.png',
 'non-vehicles/Extras/extra138.png',
 'non-vehicles/Extras/extra897.png',
 'non-vehicles/Extras/extra2740.png',
 'non-vehicles/Extras/extra5271.png',
 'non-vehicles/Extras/extra5005.png',
 'non-vehicles/GTI/image2477.png',
 'non-vehicles/GTI/image2755.png',
 'non-vehicles/Extras/extra1679.png',
 'non-vehicles/Extras/extra1052.png',
 'non-vehicles/GTI/image3167.png',
 'non-vehicles/Extras/extra4394.png',
 'non-vehicles/Extras/extra5728.png',
 'non-vehicles/Extras/extra1876.png',
 'non-vehicles/Extras/extra3881.png',
 'non-vehicles/GTI/image1944.png',
 'non-vehicles/Extras/extra2885.png',
 'non-vehicles/Extras/extra1587.png',
 'non-vehicles/Extras/extra5106.png',
 'non-vehicles/Extras/extra5684.png',
 'non-vehicles/GTI/image1822.png',
 'non-vehicles/Extras/extra5738.png',
 'non-vehicles/GTI/image3301.png',
 'non-vehicles/Extras/extra4026.png',
 'non-vehicles/GTI/image391.png',
 'non-vehicles/GTI/image168.png',
 'non-vehicles/GTI/image1036.png',
 'non-vehicles/Extras/extra3981.png',
 'non-vehicles/GTI/image1309.png',
 'non-vehicles/Extras/extra4785.png',
 'non-vehicles/Extras/extra1891.png',
 'non-vehicles/GTI/image3171.png',
 'non-vehicles/GTI/image1702.png',
 'non-vehicles/Extras/extra1674.png',
 'non-vehicles/Extras/extra2576.png',
 'non-vehicles/Extras/extra5494.png',
 'non-vehicles/Extras/extra2728.png',
 'non-vehicles/GTI/image3370.png',
 'non-vehicles/GTI/image850.png',
 'non-vehicles/Extras/extra213.png',
 'non-vehicles/GTI/image242.png',
 'non-vehicles/Extras/extra3360.png',
 'non-vehicles/Extras/extra2954.png',
 'non-vehicles/Extras/extra1854.png',
 'non-vehicles/Extras/extra1457.png',
 'non-vehicles/Extras/extra803.png',
 'non-vehicles/Extras/extra597.png',
 'non-vehicles/Extras/extra177.png',
 'non-vehicles/GTI/image492.png',
 'non-vehicles/Extras/extra1035.png',
 'non-vehicles/GTI/image1816.png',
 'non-vehicles/Extras/extra5246.png',
 'non-vehicles/Extras/extra5499.png',
 'non-vehicles/Extras/extra1559.png',
 'non-vehicles/GTI/image1159.png',
 'non-vehicles/Extras/extra1768.png',
 'non-vehicles/Extras/extra203.png',
 'non-vehicles/GTI/image2939.png',
 'non-vehicles/Extras/extra5093.png',
 'non-vehicles/GTI/image3699.png',
 'non-vehicles/GTI/image3241.png',
 'non-vehicles/Extras/extra5411.png',
 'non-vehicles/GTI/image2520.png',
 'non-vehicles/Extras/extra2455.png',
 'non-vehicles/Extras/extra4553.png',
 'non-vehicles/Extras/extra905.png',
 'non-vehicles/GTI/image1300.png',
 'non-vehicles/Extras/extra2780.png',
 'non-vehicles/Extras/extra664.png',
 'non-vehicles/Extras/extra263.png',
 'non-vehicles/GTI/image2274.png',
 'non-vehicles/GTI/image473.png',
 'non-vehicles/Extras/extra3610.png',
 'non-vehicles/GTI/image1651.png',
 'non-vehicles/Extras/extra3185.png',
 'non-vehicles/Extras/extra569.png',
 'non-vehicles/Extras/extra3983.png',
 'non-vehicles/GTI/image1683.png',
 'non-vehicles/Extras/extra2588.png',
 'non-vehicles/Extras/extra3443.png',
 'non-vehicles/Extras/extra2841.png',
 'non-vehicles/Extras/extra2694.png',
 'non-vehicles/Extras/extra1721.png',
 'non-vehicles/Extras/extra5214.png',
 'non-vehicles/GTI/image941.png',
 'non-vehicles/Extras/extra4813.png',
 'non-vehicles/GTI/image3868.png',
 'non-vehicles/Extras/extra1413.png',
 'non-vehicles/GTI/image2776.png',
 'non-vehicles/Extras/extra1554.png',
 'non-vehicles/Extras/extra740.png',
 'non-vehicles/GTI/image882.png',
 'non-vehicles/Extras/extra871.png',
 'non-vehicles/Extras/extra2643.png',
 'non-vehicles/Extras/extra1221.png',
 'non-vehicles/Extras/extra2430.png',
 'non-vehicles/GTI/image129.png',
 'non-vehicles/Extras/extra2377.png',
 'non-vehicles/GTI/image1976.png',
 'non-vehicles/GTI/image1596.png',
 ...]
In [16]:
print("len(cars):", len(cars))

print("len(non_cars):", len(non_cars))
len(cars): 8792
len(non_cars): 8968

3 Display some sample pics (car and non-car)

In [20]:
car_index1 = np.random.randint(0, len(cars))
car_index2 = np.random.randint(0, len(cars))
non_car_index1 = np.random.randint(0, len(non_cars))
non_car_index2 = np.random.randint(0, len(non_cars))

car_image1 = cv2.imread(cars[car_index1])
car_image2 = cv2.imread(cars[car_index2])
non_car_image1 = cv2.imread(non_cars[non_car_index1])
non_car_image2 = cv2.imread(non_cars[non_car_index2])

fig, axs = plt.subplots(1, 4, figsize=(15, 4))
axs = axs.ravel()

axs[0].axis('off')
axs[0].set_title('Random Car 1')
axs[0].imshow(car_image1)

axs[1].axis('off')
axs[1].set_title('Random Car 2')
axs[1].imshow(car_image2)

axs[2].axis('off')
axs[2].set_title('Random non-car 1')
axs[2].imshow(non_car_image1)

axs[3].axis('off')
axs[3].set_title('Random non-car 2')
axs[3].imshow(non_car_image2)
Out[20]:
<matplotlib.image.AxesImage at 0x7efca9362240>

4 Color Histogram Feature Extraction

In [39]:
# Define a function to compute color histogram features
# Use the code from course(Histogram of color section)

def color_hist(img, num_bins = 32, bin_range=(0, 256)):
    # Compute the histogram of the RGB channels separately
    rhist = np.histogram(img[:,:,0], bins=num_bins, range=bin_range)
    ghist = np.histogram(img[:,:,1], bins=num_bins, range=bin_range)
    bhist = np.histogram(img[:,:,2], bins=num_bins, range=bin_range)
    
    # Generating bin centers
    bin_edges = rhist[1]
    bin_centers = (bin_edges[1:]  + bin_edges[0 : len(bin_edges) - 1]) / 2
    # Concatenate the histograms into a single feature vector
    hist_features = np.concatenate((rhist[0], ghist[0], bhist[0]))
    # Return the individual histograms, bin_centers and feature vector
    return rhist, ghist, bhist, bin_centers, hist_features
In [35]:
# red histogram
r_hist = np.histogram(car_image1[:,:,0])
In [36]:
# contains the counts in each of the bins
r_hist[0]
Out[36]:
array([1556, 1037,  916,  232,   98,   93,   45,   33,   37,   49])
In [37]:
# contains the bin edges (so it is one element longer than r_hist[0]).
r_hist[1]
Out[37]:
array([   2. ,   27.3,   52.6,   77.9,  103.2,  128.5,  153.8,  179.1,
        204.4,  229.7,  255. ])
In [42]:
rh, gh, bh, bincen, feature_vec = color_hist(car_image1, num_bins=32, bin_range =(0, 256))
In [45]:
# Plot a figure with all three bar charts
if rh is not None:
    fig = plt.figure(figsize=(12, 3))
    
    plt.subplot(131)
    plt.bar(bincen, rh[0]) # plt.bar(x, y)
    plt.xlim(0, 256)
    plt.title('R Histogram')
    
    plt.subplot(132)
    plt.bar(bincen, gh[0])
    plt.xlim(0, 256)
    plt.title('G Histogram')
    
    plt.subplot(133)
    plt.bar(bincen, bh[0])
    plt.xlim(0, 256)
    plt.title('B Histogram')
    
    fig.tight_layout()
else:
    print('Your function is returning None for at least one variable...')

5 Explore the color space

In [85]:
# Use the code from course(section: Explore color space)

from mpl_toolkits.mplot3d import Axes3D

def plot3d(pixels, colors_rgb, axis_labels=list("RGB"), 
           axis_limits=((0, 255), (0, 255), (0, 255))):
    """Plot pixels in 3D."""

    # Create figure and 3D axes
    fig = plt.figure(figsize=(6, 6))
    ax = Axes3D(fig)

    # Set axis limits
    ax.set_xlim(*axis_limits[0])
    ax.set_ylim(*axis_limits[1])
    ax.set_zlim(*axis_limits[2])

    # Set axis labels and sizes
    ax.tick_params(axis='both', which='major', labelsize=7, pad=4)
    ax.set_xlabel(axis_labels[0], fontsize=16, labelpad=16)
    ax.set_ylabel(axis_labels[1], fontsize=16, labelpad=16)
    ax.set_zlabel(axis_labels[2], fontsize=16, labelpad=16)

    # Plot pixel values with colors given in colors_rgb
    ax.scatter(
        pixels[:, :, 0].ravel(),
        pixels[:, :, 1].ravel(),
        pixels[:, :, 2].ravel(),
        c=colors_rgb.reshape((-1, 3)), edgecolors='none')

    return ax  # return Axes3D object for further manipulation
In [113]:
def plot_image_color_space(img):

    # Select a small fraction of pixels to plot by subsampling it
    scale = max(img.shape[0], img.shape[1], 64) / 64  # at most 64 rows and columns
    img_small = cv2.resize(img, (np.int(img.shape[1] / scale), np.int(img.shape[0] / scale)), interpolation=cv2.INTER_NEAREST)

    # Convert subsampled image to desired color space(s)
    img_small_RGB = cv2.cvtColor(img_small, cv2.COLOR_BGR2RGB)  # OpenCV uses BGR, matplotlib likes RGB
    img_small_HSV = cv2.cvtColor(img_small, cv2.COLOR_BGR2HSV)
    img_small_LUV = cv2.cvtColor(img_small, cv2.COLOR_BGR2LUV)
    img_small_HLS = cv2.cvtColor(img_small, cv2.COLOR_BGR2HLS)
    img_small_YUV = cv2.cvtColor(img_small, cv2.COLOR_BGR2YUV)
    img_small_YCrCb = cv2.cvtColor(img_small, cv2.COLOR_BGR2YCrCb)
    img_small_rgb = img_small_RGB / 255.  # scaled to [0, 1], only for plotting
    
    # Plot and show
    plot3d(img_small_RGB, img_small_rgb, axis_labels=list("RGB"))
    plt.show()

    plot3d(img_small_HSV, img_small_rgb, axis_labels=list("HSV"))
    plt.show()
    
    plot3d(img_small_LUV, img_small_rgb, axis_labels=list("LUV"))
    plt.show()
    
    plot3d(img_small_HLS, img_small_rgb, axis_labels=list("HLS"))
    plt.show()

    plot3d(img_small_YUV, img_small_rgb, axis_labels=list("YUV"))
    plt.show()
    
    plot3d(img_small_YCrCb, img_small_rgb, axis_labels=list("YCrCb"))
    plt.show()
In [114]:
# Read a color car image
plot_image_color_space(car_image1)
In [115]:
# Read a color car image
plot_image_color_space(car_image2)
In [116]:
# Read a color non car image
plot_image_color_space(non_car_image1)
In [117]:
# Read a color non car image
plot_image_color_space(non_car_image2)

We can notice that there are some different between car and non-car images

6 Spatial Binning of Color

In [106]:
# Use the code piece from course(Section: Spatial Binning of Color)
# Define a function to compute binned color features  
def bin_spatial(img, color_space='RGB', size=(32, 32)):
    # Convert image to new color space (if specified)
    if color_space != 'RGB':
        if color_space == 'HSV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
        elif color_space == 'LUV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2LUV)
        elif color_space == 'HLS':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2HLS)
        elif color_space == 'YUV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2YUV)
        elif color_space == 'YCrCb':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb)
    else: feature_image = np.copy(img)             
    # Use cv2.resize().ravel() to create the feature vector
    features = cv2.resize(feature_image, size).ravel() 
    # Return the feature vector
    return features
In [157]:
def plot_image_bin_spatial(img):
    
    feature_vec_ycrcb = bin_spatial(img, color_space='YCrCb', size=(32, 32))
    feature_vec_rgb = bin_spatial(img, color_space='RGB', size=(32, 32))    
    feature_vec_hsv = bin_spatial(img, color_space='HSV', size=(32, 32))
    feature_vec_luv = bin_spatial(img, color_space='LUV', size=(32, 32))
    feature_vec_hls = bin_spatial(img, color_space='HLS', size=(32, 32))
    feature_vec_yuv = bin_spatial(img, color_space='YUV', size=(32, 32))
    
    
    #fig = plt.figure(figsize=(12, 6))
    f, axarr = plt.subplots(2, 3, figsize=(10,5))
    
    #plt.subplot(131)
    axarr[0, 0].plot(feature_vec_ycrcb)
    axarr[0, 0].set_title('YCrCb')
    
    #plt.subplot(132)
    axarr[0, 1].plot(feature_vec_rgb)
    axarr[0, 1].set_title('RGB')

    #plt.subplot(133)
    axarr[0, 2].plot(feature_vec_hsv)
    axarr[0, 2].set_title('HSV')
    
    #plt.subplot(231)
    axarr[1, 0].plot(feature_vec_luv)
    axarr[1, 0].set_title('LUV')
    
    #plt.subplot(232)
    axarr[1, 1].plot(feature_vec_hls)
    axarr[1, 1].set_title('HLS')
    
    #plt.subplot(233)
    axarr[1, 2].plot(feature_vec_yuv)
    axarr[1, 2].set_title('YUV')
    
    f.subplots_adjust(hspace=1, wspace=1)
In [169]:
plot_image_bin_spatial(car_image1)
In [170]:
plot_image_bin_spatial(car_image2)
In [171]:
plot_image_bin_spatial(non_car_image1)
In [172]:
plot_image_bin_spatial(non_car_image2)

7 Histogram of Oriented Gradient (HOG) Feature Extraction

In [269]:
# Use the code from course(Section: scikit-image HOG)
# Define a function to return HOG features and visualization
def get_hog_features(img, 
                     orientations, 
                     pixels_per_cell, 
                     cells_per_block, 
                     vis=False, 
                     feature_vec=True):
    if vis == True:
        features, hog_image = hog(img, 
                                  orientations = orientations, 
                                  pixels_per_cell = (pixels_per_cell, pixels_per_cell),
                                  cells_per_block = (cells_per_block, cells_per_block), 
                                  transform_sqrt=False, 
                                  visualise=True, 
                                  feature_vector=False)
        return features, hog_image
    else:      
        features = hog(img, orientations=orient, pixels_per_cell=(pixels_per_cell, pixels_per_cell),
                       cells_per_block=(cells_per_block, cells_per_block), transform_sqrt=False, 
                       visualise=False, feature_vector=feature_vec)
        return features
In [175]:
car_image1_gray = cv2.cvtColor(car_image1, cv2.COLOR_RGB2GRAY)
orientations = 32
pixels_per_cell = 16
cells_per_block = 2

# extract HOG feature and get a hog images for visualization
features, hog_image = get_hog_features(car_image1_gray, orientations, pixels_per_cell, cells_per_block, vis=True, feature_vec=False)

hog_vector = np.ravel(features)
print('HOG features.shape: ', features.shape)
print('After ravel(), feature vector: ', hog_vector.shape)

# Plot the examples
fig, ax = plt.subplots(1,2, figsize=(15, 4))
ax = ax.ravel()

ax[0].axis('off')
ax[0].set_title('Car Image 1')
ax[0].imshow(car_image1_gray, cmap='gray')

ax[1].axis('off')
ax[1].set_title('HOG Feature Visualization')
ax[1].imshow(hog_image, cmap='gray')
/home/willwywang/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/skimage/feature/_hog.py:119: skimage_deprecation:

Default value of `block_norm`==`L1` is deprecated and will be changed to `L2-Hys` in v0.15

HOG features.shape:  (3, 3, 2, 2, 32)
After ravel(), feature vector:  (1152,)
Out[175]:
<matplotlib.image.AxesImage at 0x7efc8e12ecf8>

8 Combine and Normalize Features

Combine Spatial & Color & HOG features

In [182]:
# Use code base from course(section: Combine and Normalize Features) and add HOG Feature extraction (from section: HOG Classify)
# Define a function to extract features from a list of images
# Have this function call bin_spatial() and color_hist() and get_hog_features()
def extract_features(imgs, 
                     color_space='RGB', 
                     spatial_size=(32, 32),
                     hist_bins=32, 
                     orientations=16, 
                     pixels_per_cell=16, 
                     cells_per_block=2, 
                     hog_channel='ALL'):
    # Create a list to append feature vectors to
    features = []
    # Iterate through the list of images
    for file in imgs:
        # Read in each one by one
        image = mpimg.imread(file)
        # apply color conversion if other than 'RGB'
        if color_space != 'RGB':
            if color_space == 'HSV':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
            elif color_space == 'LUV':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2LUV)
            elif color_space == 'HLS':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2HLS)
            elif color_space == 'YUV':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2YUV)
            elif color_space == 'YCrCb':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2YCrCb)
        else: feature_image = np.copy(image)      

        spatial_features = bin_spatial(feature_image, size=spatial_size)
        rh, gh, bh, bincen, hist_features = color_hist(feature_image, num_bins=32, bin_range =(0, 256))

        if hog_channel == 'ALL':
            hog_features = []
            for channel in range(feature_image.shape[2]):
                hog_features.append(get_hog_features(feature_image[:,:,channel], 
                                                     orientations, 
                                                     pixels_per_cell, 
                                                     cells_per_block, 
                                                     vis=False, 
                                                     feature_vec=True))
            hog_features = np.ravel(hog_features)
        else:
            hog_features = get_hog_features(feature_image[:,:,hog_channel], 
                                            orientations, 
                                            pixels_per_cell, 
                                            cells_per_block, 
                                            vis=False, 
                                            feature_vec=True)
        
        # Combile all feature together
        features.append(np.concatenate((spatial_features, hist_features, hog_features)))
    
    # Return list of feature vectors
    return features
In [186]:
color_space = 'YCrCb' # Can be RGB, HSV, LUV, HLS, YUV, YCrCb
orientations = 32
pixels_per_cell = 16
cells_per_block = 2
hog_channel = 'ALL' # Can be 0, 1, 2, or "ALL"
spatial_size = (32, 32)
hist_bins = 32

car_features = extract_features(cars, 
                                color_space, 
                                spatial_size, 
                                hist_bins, 
                                orientations, 
                                pixels_per_cell, 
                                cells_per_block,
                                hog_channel)

non_car_features = extract_features(non_cars, 
                                    color_space, 
                                    spatial_size,
                                    hist_bins, 
                                    orientations, 
                                    pixels_per_cell, 
                                    cells_per_block,
                                    hog_channel)
/home/willwywang/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/skimage/feature/_hog.py:119: skimage_deprecation:

Default value of `block_norm`==`L1` is deprecated and will be changed to `L2-Hys` in v0.15

Normalize combined features and visualization on them

In [205]:
# Use code from course(section: Combine and Normalize Features)

# Create an array stack of feature vectors
X = np.vstack((car_features, non_car_features)).astype(np.float64)  

# Fit a per-column scaler
X_scaler = StandardScaler().fit(X)
# Apply the scaler to X
scaled_X = X_scaler.transform(X)

car_ind = np.random.randint(0, len(cars))
non_car_ind = np.random.randint(0, len(non_cars))

f, axarr = plt.subplots(2, 3, figsize=(10,5))

#plt.subplot(131)
axarr[0, 0].imshow(mpimg.imread(cars[car_ind]))
axarr[0, 0].set_title('Original Car Image')

#plt.subplot(132)
axarr[0, 1].plot(X[car_ind])
axarr[0, 1].set_title('Raw Car Features')

#plt.subplot(133)
axarr[0, 2].plot(scaled_X[car_ind])
axarr[0, 2].set_title('Norm Car Features')

#plt.subplot(231)
axarr[1, 0].imshow(mpimg.imread(non_cars[non_car_ind]))
axarr[1, 0].set_title('Original Non Car Image')

#plt.subplot(232)
axarr[1, 1].plot(X[non_car_ind])
axarr[1, 1].set_title('Raw Car Features')

#plt.subplot(233)
axarr[1, 2].plot(scaled_X[non_car_ind])
axarr[1, 2].set_title('Norm Non Car Features')

f.subplots_adjust(hspace=1, wspace=1)

9 Prepare training data and test data set and train a Car classifier

In [215]:
# Use code base from course(Section: HOG Classify & Color Classify)

# we give 1 to car set, and 0 to non car set, generate ground truth of training data
y = np.hstack((np.ones(len(car_features)), 
               np.zeros(len(non_car_features))))


# Split the data set into training set and testting set with 8:2 ratio
rand_state = np.random.randint(0, 100)
X_train, X_test, y_train, y_test = train_test_split(scaled_X, y, test_size=0.2, random_state = rand_state)
# Use LinearSVC as our classifier model
svc = LinearSVC()
# Check the training time for the SVC
begin_time = time.time()
# Train the SVC
svc.fit(X_train, y_train)
end_time = time.time()
print('We use ', round(end_time - begin_time, 3), 'seconds training the model')

# Use Test set to test the model
print('With test set, the model score is = ', round(svc.score(X_test, y_test), 5))

# Check the prediction time for a single sample
begin_time = time.time()
n_predict = 10
print('The 10 prediction from the Model: ', svc.predict(X_test[0 : n_predict]))
print('The Ground Truth labels         : ', y_test[0:n_predict])
end_time = time.time()
print(round(end_time - begin_time, 5), 'Seconds to predict', n_predict,'labels with SVC')
We use  14.17 seconds training the model
With test set, the model score is =  0.9893
The 10 prediction from the Model:  [ 0.  0.  0.  1.  0.  1.  1.  1.  0.  0.]
The Ground Truth labels         :  [ 0.  0.  0.  1.  0.  1.  1.  1.  0.  0.]
0.00192 Seconds to predict 10 labels with SVC

10 Use Sliding Windows Technique To Find Car!

Draw boxes on a given image

In [258]:
# Draw boxes on the image, 
# Use code from course(Section: Sliding Window Implementation)

def draw_boxes(img, bboxes, color=(0, 0, 255), thick = 7):
    # make a copy of the image
    draw_img = np.copy(img)
    # draw each bounding box on your image copy using cv2.rectangle()
    for bbox in bboxes:
        # Draw a rectangle given bbox coordinates
        cv2.rectangle(draw_img, bbox[0], bbox[1], color, thick)

    # return the image copy with boxes drawn
    return draw_img # Change this line to return image copy with boxes

Implementation of Sliding Window

In [250]:
# Use code from Section: Sliding Window Implementation)

# Define a function that takes an image,
# start and stop positions in both x and y, 
# window size (x and y dimensions),  
# and overlap fraction (for both x and y)
# then return a list of windows which need to be calculated feature on it
def slide_window(img, 
                 x_start_stop=[None, None], 
                 y_start_stop=[None, None], 
                 xy_window=(64, 64), 
                 xy_overlap=(0.5, 0.5)):
    
    # If x and/or y start/stop positions not defined, set to image size
    if x_start_stop[0] == None:
        x_start_stop[0] = 0
    if x_start_stop[1] == None:
        x_start_stop[1] = img.shape[1]
    if y_start_stop[0] == None:
        y_start_stop[0] = 0
    if y_start_stop[1] == None:
        y_start_stop[1] = img.shape[0]
    
    # Compute the span of the region to be searched    
    xspan = x_start_stop[1] - x_start_stop[0]
    yspan = y_start_stop[1] - y_start_stop[0]

    # Compute the number of pixels per step in x/y
    nx_pix_per_step = np.int(xy_window[0]*(1 - xy_overlap[0]))
    ny_pix_per_step = np.int(xy_window[1]*(1 - xy_overlap[1]))
    
    # Compute the number of windows in x/y
    nx_buffer = np.int(xy_window[0]*(xy_overlap[0]))
    ny_buffer = np.int(xy_window[1]*(xy_overlap[1]))
    nx_windows = np.int((xspan-nx_buffer)/nx_pix_per_step) 
    ny_windows = np.int((yspan-ny_buffer)/ny_pix_per_step) 
    
    # Initialize a list to append window positions to
    window_list = []
    
    # Loop through finding x and y window positions
    # Note: you could vectorize this step, but in practice
    # you'll be considering windows one by one with your
    # classifier, so looping makes sense
    for ys in range(ny_windows):
        for xs in range(nx_windows):
            # Calculate window position
            startx = xs * nx_pix_per_step + x_start_stop[0]
            endx = startx + xy_window[0]
            starty = ys * ny_pix_per_step + y_start_stop[0]
            endy = starty + xy_window[1]
            
            # Append window position to list
            window_list.append(((startx, starty), (endx, endy)))
            
    # Return the list of windows
    return window_list
In [278]:
# Code from course(section Search and Classify)

# extract features for a single image
def single_img_features(img, 
                        color_space = 'RGB', 
                        spatial_size = (32, 32),
                        hist_bins = 32, 
                        orientations = 32, 
                        pixels_per_cell = 16, 
                        cells_per_block =2, 
                        hog_channel ='ALL'):
    
    #1) Define an empty list to receive features
    img_features = []
    
    #2) Apply color conversion if other than 'RGB'
    if color_space != 'RGB':
        if color_space == 'HSV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
        elif color_space == 'LUV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2LUV)
        elif color_space == 'HLS':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2HLS)
        elif color_space == 'YUV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2YUV)
        elif color_space == 'YCrCb':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb)
    else: feature_image = np.copy(img) 
        
    #3) Compute spatial features
    spatial_features = bin_spatial(feature_image, size=spatial_size)
    
    #4) Append features to list
    img_features.append(spatial_features)
        
    #5) Compute histogram features
    rh, gh,bh, bincen, hist_features = color_hist(feature_image, num_bins=hist_bins)
    
    #6) Append features to list
    img_features.append(hist_features)
        
    #7) Compute HOG features
    if hog_channel == 'ALL':
        hog_features = []
        for channel in range(feature_image.shape[2]):
            hog_features.extend(get_hog_features(feature_image[:,:,channel], 
                                                 orientations, 
                                                 pixels_per_cell, 
                                                 cells_per_block, 
                                                 vis=False, 
                                                 feature_vec=True))      
    else:
        hog_features = get_hog_features(feature_image[:,:,hog_channel], 
                                        orientations, 
                                        pixels_per_cell, 
                                        cells_per_block, 
                                        vis=False, 
                                        feature_vec=True)
    
    #8) Append features to list
    img_features.append(hog_features)

    #9) Return concatenated array of features
    return np.concatenate(img_features)
In [279]:
# Code from course(section Search and Classify)

# This function will receive a image  
# and a list of windows (output of slide_windows()) to be searched,
# then return windows for positive detection.

def search_windows(img, 
                   windows, 
                   clf, 
                   scaler, 
                   color_space = 'RGB', 
                   spatial_size = (32, 32), 
                   hist_bins = 32, 
                   hist_range = (0, 256), 
                   orientations = 32, 
                   pixels_per_cell = 16, 
                   cells_per_block = 2, 
                   hog_channel = 'ALL'):
    
    #1) Create an empty list to receive positive detection windows
    on_windows = []
    
    #2) Iterate over all windows in the list
    for window in windows:
        #3) Extract the test window from original image
        test_img = cv2.resize(img[window[0][1]:window[1][1], window[0][0]:window[1][0]], (64, 64))
        
        #4) Extract features for that window using single_img_features()
        features = single_img_features(test_img, 
                                       color_space = color_space, 
                                       spatial_size = spatial_size, 
                                       hist_bins = hist_bins, 
                                       orientations = orientations, 
                                       pixels_per_cell = pixels_per_cell, 
                                       cells_per_block = cells_per_block, 
                                       hog_channel = hog_channel)
        
        #5) Scale extracted features to be fed to classifier
        test_features = scaler.transform(np.array(features).reshape(1, -1))
        
        #6) Predict using your classifier
        prediction = clf.predict(test_features)
        
        #7) If positive (prediction == 1) then save the window
        if prediction == 1:
            on_windows.append(window)
            
    #8) Return windows for positive detections
    return on_windows
In [289]:
# Hog Sub-sampling Window Search(Code from course)
# Didn't use it for prediction
# Will try in future

def convert_color(img, conv='RGB2YCrCb'):
    if conv == 'RGB2YCrCb':
        return cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb)
    if conv == 'BGR2YCrCb':
        return cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
    if conv == 'RGB2LUV':
        return cv2.cvtColor(img, cv2.COLOR_RGB2LUV)

def find_cars(img, ystart, ystop, scale, svc, X_scaler, orientations, pixels_per_cell, cells_per_block, spatial_size, hist_bins):
    
    draw_img = np.copy(img)
    img = img.astype(np.float32)/255
    
    img_tosearch = img[ystart:ystop,:,:]
    ctrans_tosearch = convert_color(img_tosearch, conv='RGB2YCrCb')
    if scale != 1:
        imshape = ctrans_tosearch.shape
        ctrans_tosearch = cv2.resize(ctrans_tosearch, (np.int(imshape[1]/scale), np.int(imshape[0]/scale)))
        
    ch1 = ctrans_tosearch[:,:,0]
    ch2 = ctrans_tosearch[:,:,1]
    ch3 = ctrans_tosearch[:,:,2]

    # Define blocks and steps as above
    nxblocks = (ch1.shape[1] // pixels_per_cell) - cells_per_block + 1
    nyblocks = (ch1.shape[0] // pixels_per_cell) - cells_per_block + 1 
    nfeat_per_block = orientations * cells_per_block**2
    
    # 64 was the orginal sampling rate, with 8 cells and 8 pix per cell
    window = 64
    nblocks_per_window = (window // pixels_per_cell) - cells_per_block + 1
    cells_per_step = 2  # Instead of overlap, define how many cells to step
    nxsteps = (nxblocks - nblocks_per_window) // cells_per_step
    nysteps = (nyblocks - nblocks_per_window) // cells_per_step
    
    # Compute individual channel HOG features for the entire image
    hog1 = get_hog_features(ch1, orientations, pixels_per_cell, cells_per_block, feature_vec = False)
    hog2 = get_hog_features(ch2, orientations, pixels_per_cell, cells_per_block, feature_vec = False)
    hog3 = get_hog_features(ch3, orientations, pixels_per_cell, cells_per_block, feature_vec = False)
    
    for xb in range(nxsteps):
        for yb in range(nysteps):
            ypos = yb*cells_per_step
            xpos = xb*cells_per_step
            # Extract HOG for this patch
            hog_feat1 = hog1[ypos : ypos + nblocks_per_window, xpos : xpos + nblocks_per_window].ravel() 
            hog_feat2 = hog2[ypos : ypos + nblocks_per_window, xpos : xpos + nblocks_per_window].ravel() 
            hog_feat3 = hog3[ypos : ypos + nblocks_per_window, xpos : xpos + nblocks_per_window].ravel() 
            hog_features = np.hstack((hog_feat1, hog_feat2, hog_feat3))

            xleft = xpos*pixels_per_cell
            ytop = ypos*pixels_per_cell

            # Extract the image patch
            subimg = cv2.resize(ctrans_tosearch[ytop:ytop+window, xleft:xleft+window], (64,64))
          
            # Get color features
            spatial_features = bin_spatial(subimg, size=spatial_size)
            hist_features = color_hist(subimg, num_bins = hist_bins)

            # Scale features and make a prediction
            test_features = X_scaler.transform(np.hstack((spatial_features, hist_features, hog_features)).reshape(1, -1))    
            #test_features = X_scaler.transform(np.hstack((shape_feat, hist_feat)).reshape(1, -1))    
            test_prediction = svc.predict(test_features)
            
            if test_prediction == 1:
                xbox_left = np.int(xleft*scale)
                ytop_draw = np.int(ytop*scale)
                win_draw = np.int(window*scale)
                cv2.rectangle(draw_img,(xbox_left, ytop_draw+ystart),(xbox_left+win_draw,ytop_draw+win_draw+ystart),(0,0,255),6) 
                
    return draw_img
In [281]:
# ystart = 400
# ystop = 656
# scale = 1.5

# img = mpimg.imread('test_images/test1.jpg')
    
# out_img = find_cars(img, 
#                     ystart, 
#                     ystop, 
#                     scale, 
#                     svc, 
#                     X_scaler, 
#                     orientations, 
#                     pixels_per_cell, 
#                     cells_per_block, 
#                     spatial_size, 
#                     hist_bins)

# plt.imshow(out_img)
In [291]:
def get_hot_boxes (image):
    # Here we define 3 type of search schema with different searching area and step and overlap ratio.
    window_x_limits = [[None, None],
                       [40, None],
                       [400, 1280]]

    window_y_limits = [[380, 640],
                       [400, 600],
                       [440, 560]]

    window_size = [(128, 128),
                   (96, 96),
                   (64, 64)]

    window_overlap_ratio = [(0.6, 0.6),
                            (0.7, 0.7),
                            (0.8, 0.8)]
    
    draw_image = np.copy (image)
    all_hot_windows = []
    
    # iterate over previousely defined sliding windows
    for x_limits, y_limits, window_size_dst, overlap in zip (window_x_limits, 
                                                             window_y_limits, 
                                                             window_size, 
                                                             window_overlap_ratio):
        windows = slide_window(
            draw_image,
            x_start_stop = x_limits,
            y_start_stop = y_limits, 
            xy_window = window_size_dst,
            xy_overlap = overlap
        )
        hot_windows = search_windows(draw_image, 
                                     windows, 
                                     svc, 
                                     X_scaler, 
                                     color_space = color_space, 
                                     spatial_size = spatial_size, 
                                     hist_bins = hist_bins,
                                     hist_range = (0,256),
                                     orientations = orientations, 
                                     pixels_per_cell = pixels_per_cell, 
                                     cells_per_block= 2, 
                                     hog_channel= 'ALL')                          
        
        all_hot_windows.extend(hot_windows)
        
        img_1windowsize = draw_boxes(draw_image, hot_windows, color = (0, 0, 1), thick = 4)
        
    img_allwindowsize = draw_boxes(draw_image, all_hot_windows, color = (0, 0, 1),thick = 4)
    
    return all_hot_windows, img_1windowsize, img_allwindowsize
In [292]:
print('Hyper parameters and feature length: ')
print('orientations: ', orientations)
print('pixels_per_cell: ', pixels_per_cell)
print('cells_per_block: ', cells_per_block)
print('feature vector length: ', len(X_train[0]))

for image_test in glob.glob('test_images/test*.jpg'):
    # load test image:
    test_image = mpimg.imread(image_test)
    
    # normalize data
    test_image_n = test_image.astype(np.float32) / 255
                
    hot_window, img_singlewindow, img_allwindow = get_hot_boxes(test_image_n)

    plt.figure()
    plt.imshow(img_allwindow)
Hyper parameters and feature length: 
orientations:  32
pixels_per_cell:  16
cells_per_block:  2
feature vector length:  6624
/home/willwywang/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/skimage/feature/_hog.py:119: skimage_deprecation:

Default value of `block_norm`==`L1` is deprecated and will be changed to `L2-Hys` in v0.15

11 Using heatmap to do Multiple Detections & False Positives

In [293]:
# Code from course(section: Multiple Detections & False Positives)

def add_heat(heatmap, bbox_list):
    # Iterate through list of bboxes
    for box in bbox_list:
        # Add += 1 for all pixels inside each bbox
        # Assuming each "box" takes the form ((x1, y1), (x2, y2))
        heatmap[box[0][1]:box[1][1], box[0][0]:box[1][0]] += 1

    # Return updated heatmap
    return heatmap# Iterate through list of bboxes
    
def apply_threshold(heatmap, threshold):
    # Zero out pixels below the threshold
    heatmap[heatmap <= threshold] = 0
    # Return thresholded map
    return heatmap

def draw_labeled_bboxes(img, labels):
    # Iterate through all detected cars
    for car_number in range(1, labels[1]+1):
        # Find pixels with each car_number label value
        nonzero = (labels[0] == car_number).nonzero()
        # Identify x and y values of those pixels
        nonzeroy = np.array(nonzero[0])
        nonzerox = np.array(nonzero[1])
        # Define a bounding box based on min/max x and y
        bbox = ((np.min(nonzerox), np.min(nonzeroy)), (np.max(nonzerox), np.max(nonzeroy)))
        # Draw the box on the image
        cv2.rectangle(img, bbox[0], bbox[1], (0,0,255), 6)
    # Return the image
    return img
In [294]:
# Use code base from course(section: Multiple Detections & False Positives)

heatmap_combined = np.zeros_like(img_allwindow[:,:,0]).astype(np.float)

for image_test in glob.glob('test_images/test*.jpg'):
    # load test image
    test_image = mpimg.imread(image_test)
    
    # make a clone
    draw_image = np.copy(test_image)
    
    # normalize
    draw_image_norm = draw_image.astype(np.float32)/255
    
    hot_window = []
    
    hot_window, img_singlewindow, img_allwindow = get_hot_boxes(draw_image_norm)

    # Add heat to each box in box list
    heat_img = np.zeros_like(draw_image[:,:,0]).astype(np.float)
    heat = add_heat(heat_img, hot_window)
    
    # Apply threshold to help remove false positives
    heat = apply_threshold(heat, 1)

    # Visualize the heatmap when displaying    
    heatmap = np.clip(heat, 0, 255)
    heatmap_combined = heatmap_combined + heatmap

    # Find final boxes from heatmap using label function
    labels = label(heatmap)
    draw_image = draw_labeled_bboxes(np.copy(test_image), labels)

    fig = plt.figure(figsize=(12,3))
    plt.subplot(121)
    plt.imshow(draw_image)
    plt.title('Image')
    plt.subplot(122)
    plt.imshow(heatmap, cmap='hot')
    plt.title('Heat Map')
    
    fig.tight_layout()
/home/willwywang/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/skimage/feature/_hog.py:119: skimage_deprecation:

Default value of `block_norm`==`L1` is deprecated and will be changed to `L2-Hys` in v0.15

12 Define a function to process each frame from video

In [298]:
global extended_heatmap
global total_heatmap
global frame_index

def process_frame(img):  
    frame_index = 0
    extended_heatmap = []
    
    # Initialzation
    total_heatmap = np.zeros_like(img[:,:,0]).astype(np.float)
    
    # Normalization
    test_image_norm = img.astype(np.float32) / 255
    
    # Get all hot windows
    hot_window = []
    hot_window, img_singlewindow, img_allwindow = get_hot_boxes(test_image_norm)

    # Add heat to each box in box list
    heat_img = np.zeros_like(img[:,:,0]).astype(np.float)
    heat = add_heat(heat_img, hot_window)
    
    # Apply threshold to help remove false positives
    heat = apply_threshold(heat,1)

    # Visualize the heatmap when displaying    
    heatmap = np.clip(heat, 0, 255)
    
    # add current heat map to overall heap map for 10 frames
    if (frame_index < 10):
        extended_heatmap.append(heatmap) 
        frame_index += 1
        total_heatmap = heatmap
    else:
        extended_heatmap.pop(0)
        extended_heatmap.append(heatmap)
        total_heatmap -= heatmap[0]
        total_heatmap += heatmap[9]
        
    # Find final boxes from heatmap using label function
    total_heatmap = apply_threshold(total_heatmap,1)
    labels = label(total_heatmap)
    draw_img = draw_labeled_bboxes(np.copy(img), labels)
    return draw_img

13 Processing the video

In [299]:
# Libaries for video 
from moviepy.editor import VideoFileClip
from IPython.display import HTML

output_video = 'vehicle_detected_test.mp4'
clip1 = VideoFileClip("test_video.mp4")#.subclip(20,30)
white_clip = clip1.fl_image(process_frame)
%time white_clip.write_videofile(output_video, audio=False)
[MoviePy] >>>> Building video vehicle_detected_test.mp4
[MoviePy] Writing video vehicle_detected_test.mp4
 97%|█████████▋| 38/39 [01:19<00:02,  2.11s/it]
[MoviePy] Done.
[MoviePy] >>>> Video ready: vehicle_detected_test.mp4 

CPU times: user 1min 19s, sys: 0 ns, total: 1min 19s
Wall time: 1min 19s
In [300]:
HTML("""
<video width="960" height="540" controls>
  <source src="{0}">
</video>
""".format(output_video))
Out[300]:
In [ ]:
output_video2 = 'vehicle_detected.mp4'
clip2 = VideoFileClip("project_video.mp4")#.subclip(20,30)
white_clip2 = clip2.fl_image(process_frame)
%time white_clip2.write_videofile(output_video2, audio=False)
[MoviePy] >>>> Building video vehicle_detected.mp4
[MoviePy] Writing video vehicle_detected.mp4
 15%|█▍        | 183/1261 [06:11<36:43,  2.04s/it]
In [ ]:
HTML("""
<video width="960" height="540" controls>
  <source src="{0}">
</video>
""".format(output_video2))